package com.health.mapp.impl;

import java.math.BigDecimal;
import java.util.List;

import org.apache.http.util.TextUtils;
import org.apache.log4j.Logger;

import com.health.db.model.GoodsOrder;
import com.health.db.model.GoodsPriceList;
import com.health.db.model.GoodsPriceListTemp;
import com.health.db.model.RegisterOrder;
import com.health.db.model.SubRegisterOrder;
import com.health.db.model.UserCardList;
import com.health.db.model.UserCardListExt;
import com.health.db.service.order.IRegisterOrderService;
import com.health.db.service.order.ISubRegisterOrderService;
import com.health.db.service.sm.IGoodsOrderService;
import com.health.db.service.sm.IWXPayService;
import com.health.db.service.user.IGoodsPriceListService;
import com.health.db.service.user.IUserCardListService;
import com.health.mapp.bean.Header;
import com.health.mapp.bean.PayControllerWXMPReq;
import com.health.mapp.bean.PayControllerWXMPResp;
import com.health.mapp.interImpl.PayActionServerImpl;
import com.health.mapp.utils.Constant;
import com.health.mapp.utils.DateUtils;
import com.health.mapp.utils.Response;
import com.health.mapp.utils.ResultCode;
import com.health.pay.tencent.common.Signature;
import com.health.pay.tencent.protocol.unifiedorder.UnifiedorderResData;
import com.wxtools.api.IService;
import com.wxtools.bean.result.WxOAuth2AccessTokenResult;

public class PayControllerWXMPImpl implements ActionInterface {

    private static final Logger logger = Logger.getLogger(PayControllerWXH5Impl.class);

    // service import
    private IRegisterOrderService registerOrderService;
    private IGoodsPriceListService goodsPriceListService;
    private IWXPayService wXPayService;
    private ISubRegisterOrderService subRegisterOrderService;
    private IGoodsOrderService goodsOrderService;
    private IUserCardListService userCardListService;
    private IService mpService;

    @Override
    public Response execute(Header header, Object reqBean) throws Exception {

        PayControllerWXMPReq req = (PayControllerWXMPReq) reqBean;
        PayControllerWXMPResp _resp = new PayControllerWXMPResp();
        Long orderId = req.getOrderId();
        String code = req.getCode();
        String goodsType = req.getGoodsType();
        String openid=null;

        if (orderId == 0) {
            _resp.setErrorCode(ResultCode.OPERATION_LAKE_PARAMETER_ERROR);
            _resp.setErrorMsg(ResultCode.OPERATION_LAKE_PARAMETER_ERROR_NOTE);
            return _resp;
        } else if (TextUtils.isEmpty(code)) {
            _resp.setErrorCode(ResultCode.OPERATION_LAKE_PARAMETER_ERROR);
            _resp.setErrorMsg(ResultCode.OPERATION_LAKE_PARAMETER_ERROR_NOTE);
            return _resp;
        } else {

            WxOAuth2AccessTokenResult result = mpService.oauth2ToGetAccessToken(code);
            openid=result.getOpenid();
            if (TextUtils.isEmpty(openid)) {
                _resp.setErrorCode(ResultCode.OPERATION_UN_SUPPORT_PAYMENT_ERROR);
                _resp.setErrorMsg(ResultCode.OPERATION_UN_SUPPORT_PAYMENT_ERROR_NOTE);
                return _resp;
            }

            String goodsName = "";
            BigDecimal orderFee = new BigDecimal(0);
            String temOrderId = String.valueOf(orderId); // 订单号

            //子订单
            if (goodsType.equals(Constant.CONSTANTS_PAY_ACTION_ID_43.toString())) {

                temOrderId = temOrderId + "-" + String.valueOf(Constant.CONSTANTS_PAY_ACTION_ID_43);

                SubRegisterOrder currGoodsOrder = new SubRegisterOrder();
                currGoodsOrder = subRegisterOrderService.selectByPrimaryKey(orderId);


                if (null != currGoodsOrder
                        && currGoodsOrder.getRunstatusid().intValue() == Constant.CONSTANTS_ORDER_RUNSTATUS_ID_1.intValue()) {

                    //查询到用户可用的卡列表，并返回离失效时间最近的一张卡
                    UserCardListExt queryUserCardListExt = new UserCardListExt();

                    queryUserCardListExt.setOwnerid(currGoodsOrder.getUserId());
                    //增加剩余时间（次数，余额）校验，如果余额已为0 ，或是余额不够此次消费，则不返回
                    if (currGoodsOrder.getSubOrderType().intValue() == 4) {
                        queryUserCardListExt.setLefttime04(new BigDecimal(1));
                        goodsName = "送药服务";
                        List<UserCardList> list = userCardListService.selectUserCardLists(queryUserCardListExt);
                        if (list.size() > 0) {
                            SubRegisterOrder temp = new SubRegisterOrder();
                            orderFee = currGoodsOrder.getMediCharge();
                            temp.setSubOrderId(orderId);
                            temp.setExpendCard((short) 1);
                            subRegisterOrderService.updateOrderSelective(temp);
                        } else {

                            orderFee = currGoodsOrder.getMediCharge().add(currGoodsOrder.getServerCharge());
                        }

                    } else if (currGoodsOrder.getSubOrderType().intValue() == 5) {
                        goodsName = "挂号服务";
                        orderFee = currGoodsOrder.getServerCharge();
                    } else {
                        _resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
                        _resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
                        return _resp;
                    }
                } else {
                    _resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
                    _resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
                    return _resp;
                }


            } else
                //商品订单
                if (goodsType.equals(Constant.CONSTANTS_PAY_ACTION_ID_51.toString())) {


                    temOrderId = temOrderId + "-" + String.valueOf(Constant.CONSTANTS_PAY_ACTION_ID_51);

                    GoodsOrder currGoodsOrder = new GoodsOrder();
                    currGoodsOrder = goodsOrderService.selectByPrimaryKey(orderId);

                    if (null != currGoodsOrder
                            && currGoodsOrder.getRunstatusid().intValue() == Constant.CONSTANTS_ORDER_RUNSTATUS_ID_1.intValue()) {
                        goodsName = currGoodsOrder.getGoodsName();
                        orderFee = currGoodsOrder.getTotal();

                    } else {
                        _resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
                        _resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
                        return _resp;
                    }


                } else
                    //商品订单
                    if (goodsType.equals(Constant.CONSTANTS_PAY_ACTION_ID_41.toString())) {


                        temOrderId = temOrderId + "-" + String.valueOf(Constant.CONSTANTS_PAY_ACTION_ID_41);

                        GoodsOrder currGoodsOrder = new GoodsOrder();
                        currGoodsOrder = goodsOrderService.selectByPrimaryKey(orderId);

                        if (null != currGoodsOrder
                                && currGoodsOrder.getRunstatusid().intValue() == Constant.CONSTANTS_ORDER_RUNSTATUS_ID_1.intValue()) {
                            goodsName = currGoodsOrder.getGoodsName();
                            orderFee = currGoodsOrder.getTotal();

                        } else {
                            _resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
                            _resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
                            return _resp;
                        }


                    } else {

                        RegisterOrder currRegisterOrder = registerOrderService.selectSimpleSingleByOrderId(orderId);

                        if (currRegisterOrder == null
                                || currRegisterOrder.getRegistertypeid().intValue() == Constant.CONSTANTS_ORDER_FREE_ID_0.intValue()) {
                            _resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
                            _resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
                            return _resp;
                        } else {

                            /******************* 订单数据 **********************************/
                            orderFee = currRegisterOrder.getRegisterTotal(); // 价格
                            /******************* 订单数据 **********************************/

                            GoodsPriceList example = new GoodsPriceList();

                            Long docId = currRegisterOrder.getAccepterid();
                            if (null != docId) {
                                example.setSerialIdno(currRegisterOrder.getAccepterid().toString());
                            } else {
                                example.setSerialIdno(null);
                            }
                            example.setGoodsid(currRegisterOrder.getGoodsid().intValue());
                            example.setColumnid((short) 1);
                            GoodsPriceListTemp goodsPriceList = goodsPriceListService.selectByGoodsIdDocIdSingle(example);

                            if (null != goodsPriceList) {
                                // 商品名称
                                goodsName = goodsPriceList.getGoodsName(); // 商品名称;

                            } else {
                                _resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_4001);
                                _resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_4001_NOTE);
                                return _resp;
                            }
                        }
                    }

            /*************************************支付ACTION************************************************************/

            PayActionServerImpl impl = new PayActionServerImpl();

            Long payCashId = impl.cleanExpiredPayment(temOrderId, Constant.CONSTANTS_PAYMENT_WEIXIN);

            UnifiedorderResData resData;
            if (null != payCashId) {
                resData = wXPayService.unifiedMPorder("WEB", "首儿健康汇-" + goodsName, null, null, String.valueOf(payCashId) + "-" + String.valueOf(temOrderId),
                        String.valueOf(orderFee.setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100d)).intValue()), req.getClientIP(), null, null, null, openid, null);
                //保存微信支付生成的字符串
                impl.updateWXNonceStrPaymentLog(payCashId, resData.getNonce_str());
            } else {
                _resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
                _resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
                return _resp;
            }
            if (null == resData || resData.getReturn_code() == null) {
                logger
                        .error("Case1:统一下单API请求逻辑错误，请仔细检测传过去的每一个参数是否合法，或是看API能否被正常访问");
                _resp
                        .setErrorCode(ResultCode.OPERATION_ORDER_ERROR_4001);
                _resp
                        .setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_4001_NOTE);
                return _resp;
            }

            if (resData.getReturn_code().equals("FAIL")) {
                // /注意：一般这里返回FAIL是出现系统级参数错误，请检测Post给API的数据是否规范合法
                logger
                        .error("Case2:统一下单API系统返回失败，请检测Post给API的数据是否规范合法");
                _resp
                        .setErrorCode(ResultCode.OPERATION_ORDER_ERROR_4001);
                _resp
                        .setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_4001_NOTE);
                return _resp;
            } else {
                if (!Signature
                        .checkIsSignValidFromResponseString(resData
                                .getUnifiedorderServiceResponseString())) {
                    logger
                            .error("Case3:统一下单请求API返回的数据签名验证失败，有可能数据被篡改了");
                    _resp
                            .setErrorCode(ResultCode.OPERATION_ORDER_ERROR_4001);
                    _resp
                            .setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_4001_NOTE);
                    return _resp;
                }

                if (resData.getResult_code().equals("FAIL")) {
                    logger.error("出错，错误码：" + resData.getErr_code()
                            + "     错误信息：" + resData.getErr_code_des());
                    logger.error("Case4:【统一下单失败】");
                    // 退款失败时再怎么延时查询退款状态都没有意义，这个时间建议要么再手动重试一次，依然失败的话请走投诉渠道进行投诉
                    _resp
                            .setErrorCode(ResultCode.OPERATION_ORDER_ERROR_4001);
                    _resp
                            .setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_4001_NOTE);
                    return _resp;
                } else {
                    // 统一下单成功
                    logger.info("Case5:【统一下单成功】");
                    _resp.setErrorCode(ResultCode.OPERATION_SUCCESS);
                    _resp.setErrorMsg(ResultCode.OPERATION_SUCCESS_NOTE);
                    _resp.setAppid(resData.getAppid());
                    _resp.setTimeStamp(String.valueOf(DateUtils.millisSecond()));
                    _resp.setNonceStr(resData.getNonce_str());
                    _resp.setPackageName("prepay_id="+resData.getPrepay_id());
                    _resp.setSignType("MD5");
                    String sign = Signature.getSign(_resp.toMap());
                    _resp.setPaySign(sign);
                    return _resp;
                }


            }
        }

    }

    public static Logger getLogger() {
        return logger;
    }

    public IRegisterOrderService getRegisterOrderService() {
        return registerOrderService;
    }

    public void setRegisterOrderService(IRegisterOrderService registerOrderService) {
        this.registerOrderService = registerOrderService;
    }

    public IGoodsPriceListService getGoodsPriceListService() {
        return goodsPriceListService;
    }

    public void setGoodsPriceListService(IGoodsPriceListService goodsPriceListService) {
        this.goodsPriceListService = goodsPriceListService;
    }

    public IWXPayService getwXPayService() {
        return wXPayService;
    }

    public void setwXPayService(IWXPayService wXPayService) {
        this.wXPayService = wXPayService;
    }

    public ISubRegisterOrderService getSubRegisterOrderService() {
        return subRegisterOrderService;
    }

    public void setSubRegisterOrderService(ISubRegisterOrderService subRegisterOrderService) {
        this.subRegisterOrderService = subRegisterOrderService;
    }

    public IGoodsOrderService getGoodsOrderService() {
        return goodsOrderService;
    }

    public void setGoodsOrderService(IGoodsOrderService goodsOrderService) {
        this.goodsOrderService = goodsOrderService;
    }

    public IUserCardListService getUserCardListService() {
        return userCardListService;
    }

    public void setUserCardListService(IUserCardListService userCardListService) {
        this.userCardListService = userCardListService;
    }

    public IService getMpService() {
        return mpService;
    }

    public void setMpService(IService mpService) {
        this.mpService = mpService;
    }
}
